package pub.cleangao.mybatis.execution;

import lombok.Data;
import lombok.EqualsAndHashCode;
import pub.cleangao.mybatis.expression.WhereExpression;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


@EqualsAndHashCode(callSuper = true)
@Data
public class UpdateExecution extends AbstractExecution {

    public static UpdateExecution startUpdate(String table) {
        UpdateExecution execution = new UpdateExecution();
        execution.setTable(table);
        execution.setUpdateValues(new HashMap<>());
        return execution;
    }

    private String table;
    private Map<String, Object> updateValues;
    private List<WhereExpression> whereExpressionList;

    public void addValuesMap(Map<String, Object> mapValues) {
        updateValues.putAll(mapValues);
    }

    public void addValuesByColumn(List<String> columns, List<Object> values) {
        for (int i = 0; i < columns.size(); i++) {
            updateValues.put(columns.get(i), values.get(i));
        }
    }

    public void addValuesPlain(String[] plainValues) {
        int half = plainValues.length / 2;
        for (int i = 0; i < half; i++) {
            updateValues.put(plainValues[i], plainValues[i + half]);
        }
    }

    @Override
    public Object runInDataSource(Connection connection) throws SQLException {

        if (whereExpressionList == null || whereExpressionList.isEmpty()) {
            throw new SQLException("where condition is required for DELETE operation.");
        }
        whereExpressionList.sort((o1, o2) -> {
            return o1.index() - o2.index();
        });
        StringBuilder sql = new StringBuilder();
        sql.append("UPDATE ");
        sql.append(table);
        sql.append(" SET ");
        for (Map.Entry<String, Object> entry : updateValues.entrySet()) {
            sql.append(entry.getKey());
            sql.append(" = ");
            sql.append(entry.getValue());
            sql.append(" ,");
        }
        sql.delete(sql.length() - 1, sql.length());
        sql.append(" WHERE ");
        PreparedStatement statement = connection.prepareStatement(generateWhereClause(sql, whereExpressionList));
        return statement.executeUpdate();
    }
}
